from sqlalchemy import and_
from datetime import datetime

from app.dao import Session
from app.models import User
from app.parameter import LoginParam,RegisterParam,UpdateUserInfoParam
from app.utils import Response, tokenEncode
from app.constant import ERRORCODE
from utils import DEBUG,ERROR

class UserService():
    SEVEN_DAYS_SECOND = 7 * 24 * 60 * 60;
    
    @staticmethod
    def login(loginParam: LoginParam):
        user = None
        with Session() as session:
            user = session.query(User).filter(
                and_(
                    User.username == loginParam.username, 
                    User.password == loginParam.password)
                ).first()
        
        if user == None:
            return Response(ERRORCODE.REQUEST_USERNAME_OR_PASSWORD_ERROR)
        else:
            res = user.to_dict()
            DEBUG(res)
            token = None
            if loginParam.keep == 0:
                token = tokenEncode(payload=res)
            elif loginParam.keep > 0:
                token = tokenEncode(payload=res, exp = int(datetime.now().timestamp()) + UserService.SEVEN_DAYS_SECOND)
            else:
                token = tokenEncode(payload=res, exp = -1)
            return Response(ERRORCODE.RESPONSE_SUCCESS, {"user": user, "token": token})        
    
    @staticmethod
    def register(registerParam :RegisterParam):
        try:
            with Session() as session:
                user = session.query(User).filter(User.username == registerParam.username).first()
                if user != None:
                    return Response(ERRORCODE.REQUEST_USERNAME_ALREADY_EXIST)
                user = session.query(User).filter(User.nickname == registerParam.nickname).first()
                if user != None:
                    return Response(ERRORCODE.REQUEST_USERNICKNAME_ALREADY_EXIST)

                user = User(username=registerParam.username, password = registerParam.password, 
                            nickname = registerParam.nickname)
        
                session.add(user)
                session.commit()
                return Response(ERRORCODE.RESPONSE_SUCCESS, None) 
        except Exception as e:
            ERROR(e)
            return Response(ERRORCODE.RESPONSE_DATABASE_OPERATION_ERROR, None)
            
    @staticmethod
    def updateUserInfo(updateUserInfo :UpdateUserInfoParam):
        
        try:
            with Session() as session:
                if updateUserInfo.userId <= 0:
                    return Response(ERRORCODE.REQUEST_DATAFORMATION_ERROR, None)
                updateData = {}
                if updateUserInfo.nickname != None:
                    updateData[User.nickname] = updateUserInfo.nickname
                if updateUserInfo.password != None:
                    updateData[User.password] = updateUserInfo.password
                if updateUserInfo.avatar != None:
                    updateData[User.avatar] = updateUserInfo.avatar
                
                session.query(User).filter_by(id=updateUserInfo.userId).update(updateData)
                session.commit()
                
                return Response(ERRORCODE.RESPONSE_SUCCESS, updateUserInfo)
        except Exception as e:
            ERROR(e)
            return Response(ERRORCODE.RESPONSE_DATABASE_OPERATION_ERROR, None)
            